<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        // 1、防抖
        // 每次触发定时器后，取消上一个定时器，然后重新触发定时器。防抖一般用于用户未知行为的优化，比如搜索框输入弹窗提示，
        // 因为用户接下来要输入的内容都是未知的，所以每次用户输入就弹窗是没有意义的，需要等到用户输入完毕后再进行弹窗提示。
        // 防抖在连续的事件，只需触发一次回调的场景有：
        // 1.搜索框搜索输入。只需用户最后一次输入完，再发送请求
        // 2.手机号、邮箱验证输入检测
        // 3.窗口大小resize。只需窗口调整完成后，计算窗口大小。防止重复渲染。
        function debounce(fn, delay) {
            let timer; // 维护一个 timer
            return function () {
                var _this = this; // 取debounce执行作用域的this(原函数挂载到的对象)
                var args = arguments;
                if (timer) {
                    clearTimeout(timer);
                }
                timer = setTimeout(function () {
                    fn.apply(_this, args); // 用apply指向调用debounce的对象，相当于_this.fn(args);
                }, delay);
            };
        }

        // 调用​
        input1.addEventListener('keyup', debounce(() => {
            console.log(input1.value)
        }), 600)

        // 2、节流
        // 每次触发定时器后，直到这个定时器结束之前无法再次触发。一般用于可预知的用户行为的优化，比如为scroll事件的回调函数添加定时器。
        // 节流在间隔时间内只执行一次回调的场景有：
        // 1.滚动加载，加载更多或滚到底部监听
        // 2.搜索框，搜索联想功能
        // 3.按钮点击事件
        // 4.表单提交事件
        function throttle(fn, delay) {
            let timer;
            return function () {
                var _this = this;
                var args = arguments;
                if (timer) {
                    return;
                }
                timer = setTimeout(function () {
                    fn.apply(_this, args); // 这里args接收的是外边返回的函数的参数，不能用arguments
                    // fn.apply(_this, arguments); 需要注意：Chrome 14 以及 Internet Explorer 9 仍然不接受类数组对象。如果传入类数组对象，它们会抛出异常。
                    timer = null; // 在delay后执行完fn之后清空timer，此时timer为假，throttle触发可以进入计时器
                }, delay)
            }
        }

        div1.addEventListener('drag', throttle((e) => {
            console.log(e.offsetX, e.offsetY)
        }, 100))
    </script>
</body>

</html>